package com.optitronics.controllers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import com.optitronics.beans.Product;
import com.optitronics.beans.ResellerOrder;
import com.optitronics.beans.ShoppingCart;
import com.optitronics.beans.ShoppingCartItem;
import com.optitronics.service.MailSendingService;
import com.optitronics.service.ReportService;
import com.optitronics.service.UserService;
import com.optitronics.ui.ComboBoxSupport;
import com.optitronics.util.OptitronicsConstants;
import com.optitronics.validators.ShoppingCartValidator;

/**
 * Controller that handles shopping card actions
 * 
 * @author Bojan Vukotic
 * 
 */
@Controller
@RequestMapping("/shoppingCart")
@SessionAttributes("shoppingCartItem")
public class ShoppingCartController {

	private Log logger = LogFactory.getLog(this.getClass());

	@Autowired
	private ShoppingCart shoppingCart;

	@Autowired
	private ShoppingCartValidator validator;

	@Autowired
	private MessageSource messageSource;

	@Autowired
	private ReportService reportService;

	@Autowired
	private UserService userService;

	@Autowired
	private MailSendingService mailSendingService;

	@RequestMapping(value = "/newItem/{productId}", method = RequestMethod.GET)
	public String newItemForm(@PathVariable("productId") Integer productId, Model model) {

		userService.checkProductActive(productId);
		Product product = Product.findProduct(productId);

		ShoppingCartItem item = new ShoppingCartItem(product);

		model.addAttribute("product", product);
		model.addAttribute("shoppingCartItem", item);
		referenceData(product, model);

		return "shoppingCart/newItem";
	}

	private void referenceData(Product product, Model model) {
		Integer[] orderTypes = Product.getOrderTypes(product);

		Collection<ComboBoxSupport> orderTypesSupports = new ArrayList<ComboBoxSupport>();
		for (Integer orderType : orderTypes) {
			orderTypesSupports.add(new ComboBoxSupport(orderType, messageSource.getMessage("label.order.type."
					+ orderType, null, LocaleContextHolder.getLocale())));
		}

		model.addAttribute("orderTypes", orderTypesSupports);

		model.addAttribute("ORDER_TYPE_NEW", OptitronicsConstants.ORDER_TYPE_NEW);
		model.addAttribute("ORDER_TYPE_RENEWAL", OptitronicsConstants.ORDER_TYPE_RENEWAL);
		model.addAttribute("ORDER_TYPE_ACADEMIC", OptitronicsConstants.ORDER_TYPE_ACADEMIC);
		model.addAttribute("ORDER_TYPE_STUDENT", OptitronicsConstants.ORDER_TYPE_STUDENT);
		model.addAttribute("ORDER_TYPE_PENSIONER", OptitronicsConstants.ORDER_TYPE_PENSIONER);
		model.addAttribute("ORDER_TYPE_NUNS", OptitronicsConstants.ORDER_TYPE_NUNS);
		model.addAttribute("ORDER_GRAPHIC_DESIGNER", OptitronicsConstants.ORDER_GRAPHIC_DESIGNER);
		model.addAttribute("TAX_PERCENT", OptitronicsConstants.TAX_PERCENT);
		model.addAttribute("PURPOSE_COMPANIES", Product.PURPOSE_COMPANIES);
		model.addAttribute("PURPOSE_PERSONS", Product.PURPOSE_PERSONS);
	}

	@RequestMapping(value = "/{itemId}/edit", method = RequestMethod.GET)
	public String editItemForm(@PathVariable("itemId") Long itemId, Model model) {

		ShoppingCartItem item = shoppingCart.getItemById(itemId);
		Product product = Product.findProduct(item.getProductId());

		model.addAttribute("product", product);
		model.addAttribute("shoppingCartItem", item);
		referenceData(product, model);

		return "shoppingCart/newItem";
	}

	@RequestMapping(method = RequestMethod.POST, value = { "/newItem/{productId}", "/{itemId}/edit" })
	public String submitItem(Model model, @ModelAttribute("shoppingCartItem") ShoppingCartItem item,
			BindingResult result, SessionStatus status) {

		validator.validateNewItem(item, result);
		if (result.hasErrors()) {
			Product product = item.getProduct();
			shoppingCart.recalculateShoppingCartItem(item);
			model.addAttribute("product", product);
			model.addAttribute("shoppingCartItem", item);
			referenceData(product, model);
			return "shoppingCart/newItem";
		} else {
			shoppingCart.addItemToShoppingCart(item);
			status.setComplete();
			return "redirect:/shoppingCart/show";
		}
	}

	@RequestMapping(value = "/save")
	public String saveShoppingCart(Model model) {

		ResellerOrder order = null;
		try {
			order = shoppingCart.saveShoppingCart();
			List<String> fileNames = reportService.generateOrderExcels(order.getId());
			fileNames.addAll(reportService.getPDFsForOrder(order.getId()));

			mailSendingService.sendXLSMail(order, fileNames);
		} catch (Exception ex) {
			logger.error("Error generating excel file", ex);
		}

		model.addAttribute("message", "label.reseller.registration.complete");
		return "redirect:/resellerorders/" + order.getId() + "?saved=true";
	}

	@RequestMapping(value = "/show")
	public String showShoppingCart(Model model) {
		model.addAttribute("shoppingCart", shoppingCart);
		boolean placeOrder = !shoppingCart.getItems().isEmpty();
		model.addAttribute("placeOrder", placeOrder);

		return "shoppingCart/show";
	}

	@RequestMapping(value = "/{itemId}/delete")
	public String removeShoppingCartItem(@PathVariable("itemId") Long itemId, Model model) {
		shoppingCart.removeShoppingCartItem(itemId);
		return "redirect:/shoppingCart/show";
	}
}
